package com.lk.security.authentication.code;

import com.lk.security.authentication.CustomAuthenticationFailureHandler;
import com.lk.security.authentication.exception.ValidateCodeException;
import com.lk.security.properties.SecurityProperties;
import com.wf.captcha.utils.CaptchaUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @program: lk-security-parent
 * @description: 图形验证码过滤器-所有请求之前被调用一次
 * @author: Aspirin
 * @create: 2020-05-27 22:22
 */
@Component("imageCodeValidateFilter")
public class ImageCodeValidateFilter extends OncePerRequestFilter {

  @Autowired SecurityProperties securityProperties;
  @Autowired CustomAuthenticationFailureHandler customAuthenticationFailureHandler;

  @Override
  protected void doFilterInternal(
      HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
      throws ServletException, IOException {
    // 1. 如果是post方法的登录请求，则校验输入的验证码是否正确
    if (securityProperties
            .getAuthentication()
            .getLoginProcessingUrl()
            .equals(request.getRequestURI())
        && "post".equalsIgnoreCase(request.getMethod())) {
      try {
        // 校验验证码合法性
        validate(request);
      } catch (AuthenticationException e) {
        // 交给失败处理器进行处理异常
        customAuthenticationFailureHandler.onAuthenticationFailure(request, response, e);
        //  一定要记得结束
        return;
      }
    }
    // 2. 验证通过放行请求
    filterChain.doFilter(request, response);
  }

  private void validate(HttpServletRequest request) {
    // 获取用户输入的验证码
    String inputCode = request.getParameter("code");
    // 判断是否正确 首先判空
    if (StringUtils.isBlank(inputCode)) {
      throw new ValidateCodeException("验证码不能为空");
    }
    if (!CaptchaUtil.ver(inputCode, request)) {
      // 清除session中的验证码
      CaptchaUtil.clear(request);
      throw new ValidateCodeException("验证码输入错误");
    }
  }
}
